home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / gfx / show / gs_src_gs.lha / gs5.03 / gsline.c < prev    next >
C/C++ Source or Header  |  1997-01-15  |  8KB  |  303 lines

  1. /* Copyright (C) 1989, 1995, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gsline.c */
  20. /* Line parameter operators for Ghostscript library */
  21. #include "math_.h"
  22. #include "memory_.h"
  23. #include "gx.h"
  24. #include "gserrors.h"
  25. #include "gxfixed.h"            /* ditto */
  26. #include "gxmatrix.h"            /* for gzstate */
  27. #include "gzstate.h"
  28. #include "gsline.h"            /* for prototypes */
  29. #include "gzline.h"
  30.  
  31. /* ------ Device-independent parameters ------ */
  32.  
  33. #define pgs_lp gs_currentlineparams_inline(pgs)
  34.  
  35. /* setlinewidth */
  36. int
  37. gs_setlinewidth(gs_state *pgs, floatp width)
  38. {    gx_set_line_width(pgs_lp, width);
  39.     return 0;
  40. }
  41.  
  42. /* currentlinewidth */
  43. float
  44. gs_currentlinewidth(const gs_state *pgs)
  45. {    return gx_current_line_width(pgs_lp);
  46. }
  47.  
  48. /* setlinecap */
  49. int
  50. gs_setlinecap(gs_state *pgs, gs_line_cap cap)
  51. {    if ( (uint)cap > gs_line_cap_max )
  52.       return_error(gs_error_rangecheck);
  53.     pgs_lp->cap = cap;
  54.     return 0;
  55. }
  56.  
  57. /* currentlinecap */
  58. gs_line_cap
  59. gs_currentlinecap(const gs_state *pgs)
  60. {    return pgs_lp->cap;
  61. }
  62.  
  63. /* setlinejoin */
  64. int
  65. gs_setlinejoin(gs_state *pgs, gs_line_join join)
  66. {    if ( (uint)join > gs_line_join_max )
  67.       return_error(gs_error_rangecheck);
  68.     pgs_lp->join = join;
  69.     return 0;
  70. }
  71.  
  72. /* currentlinejoin */
  73. gs_line_join
  74. gs_currentlinejoin(const gs_state *pgs)
  75. {    return pgs_lp->join;
  76. }
  77.  
  78. /* setmiterlimit */
  79. int
  80. gx_set_miter_limit(gx_line_params *plp, floatp limit)
  81. {    if ( limit < 1.0 )
  82.       return_error(gs_error_rangecheck);
  83.     plp->miter_limit = limit;
  84.     /*
  85.      * Compute the miter check value.  The supplied miter limit is an
  86.      * upper bound on 1/sin(phi/2); we convert this to a lower bound on
  87.      * tan(phi).  Note that if phi > pi/2, this is negative.  We use the
  88.      * half-angle and angle-sum formulas here to avoid the trig functions.
  89.      * We also need a special check for phi/2 close to pi/4.
  90.      * Some C compilers can't handle this as a conditional expression....
  91.      */
  92.       {    double limit_squared = limit * limit;
  93.         if ( limit_squared < 2.0001 && limit_squared > 1.9999 )
  94.           plp->miter_check = 1.0e6;
  95.         else
  96.           plp->miter_check =
  97.             sqrt(limit_squared - 1) * 2 / (limit_squared - 2);
  98.       }
  99.     return 0;
  100. }
  101. int
  102. gs_setmiterlimit(gs_state *pgs, floatp limit)
  103. {    return gx_set_miter_limit(pgs_lp, limit);
  104. }
  105.  
  106. /* currentmiterlimit */
  107. float
  108. gs_currentmiterlimit(const gs_state *pgs)
  109. {    return pgs_lp->miter_limit;
  110. }
  111.  
  112. /* setdash */
  113. int
  114. gx_set_dash(gx_dash_params *dash, const float *pattern, uint length,
  115.   floatp offset, gs_memory_t *mem)
  116. {    uint n = length;
  117.     const float *dfrom = pattern;
  118.     bool ink = true;
  119.     int index = 0;
  120.     float pattern_length = 0.0;
  121.     float dist_left;
  122.     float *ppat = dash->pattern;
  123.  
  124.     /* Check the dash pattern. */
  125.     while ( n-- )
  126.     {    float elt = *dfrom++;
  127.         if ( elt < 0 )
  128.           return_error(gs_error_rangecheck);
  129.         pattern_length += elt;
  130.     }
  131.     if ( length == 0 )        /* empty pattern */
  132.     {    dist_left = 0.0;
  133.         if ( mem && ppat )
  134.           { gs_free_object(mem, ppat, "gx_set_dash(old pattern)");
  135.             ppat = 0;
  136.           }
  137.     }
  138.     else
  139.     {    uint size = length * sizeof(float);
  140.         if ( pattern_length == 0 )
  141.           return_error(gs_error_rangecheck);
  142.         /* Compute the initial index, ink_on, and distance left */
  143.         /* in the pattern, according to the offset. */
  144. #define f_mod(a, b) ((a) - floor((a) / (b)) * (b))
  145.         if ( length & 1 )
  146.         {    /* Odd and even repetitions of the pattern */
  147.             /* have opposite ink values! */
  148.             float length2 = pattern_length * 2;
  149.             dist_left = f_mod(offset, length2);
  150.             if ( dist_left >= pattern_length )
  151.               dist_left -= pattern_length, ink = !ink;
  152.         }
  153.         else
  154.           dist_left = f_mod(offset, pattern_length);
  155.         while ( (dist_left -= pattern[index]) >= 0 &&
  156.                 (dist_left > 0 || pattern[index] != 0)
  157.               )
  158.           ink = !ink, index++;
  159.         if ( mem )
  160.           { if ( ppat == 0 )
  161.               ppat = (float *)gs_alloc_bytes(mem, size,
  162.                              "gx_set_dash(pattern)");
  163.             else if ( length != dash->pattern_size )
  164.               ppat = gs_resize_object(mem, ppat, size,
  165.                           "gx_set_dash(pattern)");
  166.             if ( ppat == 0 )
  167.               return_error(gs_error_VMerror);
  168.           }
  169.         memcpy(ppat, pattern, length * sizeof(float));
  170.     }
  171.     dash->pattern = ppat;
  172.     dash->pattern_size = length;
  173.     dash->offset = offset;
  174.     dash->pattern_length = pattern_length;
  175.     dash->init_ink_on = ink;
  176.     dash->init_index = index;
  177.     dash->init_dist_left = -dist_left;
  178.     return 0;
  179. }
  180. int
  181. gs_setdash(gs_state *pgs, const float *pattern, uint length, floatp offset)
  182. {    return gx_set_dash(&pgs_lp->dash, pattern, length, offset,
  183.                pgs->memory);
  184. }
  185.  
  186. /* currentdash */
  187. uint
  188. gs_currentdash_length(const gs_state *pgs)
  189. {    return pgs_lp->dash.pattern_size;
  190. }
  191. const float *
  192. gs_currentdash_pattern(const gs_state *pgs)
  193. {    return pgs_lp->dash.pattern;
  194. }
  195. float
  196. gs_currentdash_offset(const gs_state *pgs)
  197. {    return pgs_lp->dash.offset;
  198. }
  199.  
  200. /* Internal accessor for line parameters */
  201. const gx_line_params *
  202. gs_currentlineparams(const gs_imager_state *pis)
  203. {    return gs_currentlineparams_inline(pis);
  204. }
  205.  
  206. /* ------ Device-dependent parameters ------ */
  207.  
  208. /* setflat */
  209. int
  210. gs_imager_setflat(gs_imager_state *pis, floatp flat)
  211. {    if ( flat <= 0.2 )
  212.       flat = 0.2;
  213.     else if ( flat > 100 )
  214.       flat = 100;
  215.     pis->flatness = flat;
  216.     return 0;
  217. }
  218. int
  219. gs_setflat(gs_state *pgs, floatp flat)
  220. {    return gs_imager_setflat((gs_imager_state *)pgs, flat);
  221. }
  222.  
  223. /* currentflat */
  224. float
  225. gs_currentflat(const gs_state *pgs)
  226. {    return pgs->flatness;
  227. }
  228.  
  229. /* setstrokeadjust */
  230. int
  231. gs_setstrokeadjust(gs_state *pgs, bool stroke_adjust)
  232. {    pgs->stroke_adjust = stroke_adjust;
  233.     return 0;
  234. }
  235.  
  236. /* currentstrokeadjust */
  237. bool
  238. gs_currentstrokeadjust(const gs_state *pgs)
  239. {    return pgs->stroke_adjust;
  240. }
  241.  
  242. /* ------ Extensions ------ */
  243.  
  244. /* Device-independent */
  245.  
  246. /* setdashadapt */
  247. void
  248. gs_setdashadapt(gs_state *pgs, bool adapt)
  249. {    pgs_lp->dash.adapt = adapt;
  250. }
  251.  
  252. /* currentdashadapt */
  253. bool
  254. gs_imager_currentdashadapt(const gs_imager_state *pis)
  255. {    return gs_currentlineparams_inline(pis)->dash.adapt;
  256. }
  257. bool
  258. gs_currentdashadapt(const gs_state *pgs)
  259. {    return gs_imager_currentdashadapt((const gs_imager_state *)pgs);
  260. }
  261.  
  262. /* Device-dependent */
  263.  
  264. /* setaccuratecurves */
  265. void
  266. gs_setaccuratecurves(gs_state *pgs, bool accurate)
  267. {    pgs->accurate_curves = accurate;
  268. }
  269.  
  270. /* currentaccuratecurves */
  271. bool
  272. gs_imager_currentaccuratecurves(const gs_imager_state *pis)
  273. {    return pis->accurate_curves;
  274. }
  275. bool
  276. gs_currentaccuratecurves(const gs_state *pgs)
  277. {    return gs_imager_currentaccuratecurves((const gs_imager_state *)pgs);
  278. }
  279.  
  280. /* setdotlength */
  281. int
  282. gx_set_dot_length(gx_line_params *plp, floatp length, bool absolute)
  283. {    if ( length < 0 )
  284.       return_error(gs_error_rangecheck);
  285.     plp->dot_length = length;
  286.     plp->dot_length_absolute = absolute;
  287.     return 0;
  288. }
  289. int
  290. gs_setdotlength(gs_state *pgs, floatp length, bool absolute)
  291. {    return gx_set_dot_length(pgs_lp, length, absolute);
  292. }
  293.  
  294. /* currentdotlength */
  295. float
  296. gs_currentdotlength(const gs_state *pgs)
  297. {    return pgs_lp->dot_length;
  298. }
  299. bool
  300. gs_currentdotlength_absolute(const gs_state *pgs)
  301. {    return pgs_lp->dot_length_absolute;
  302. }
  303.